package com.ruoyi.web.controller.system;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.domain.vo.QueryVo;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.*;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
@RequestMapping("/system/regulated_data")
public class RegulatedDataController extends BaseController {
    @Autowired
    private IProjectService projectService;

    @Autowired
    private IAlarmService alarmService;

    @Autowired
    private IDeviceService deviceService;

    @Autowired
    private IProductService productService;

    @Autowired
    private ISysDeptService sysDeptService;

    @Autowired
    private IReportDetailService reportDetailService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private TokenService tokenService;
    @Autowired
    private ICustomPermissionService customPermissionService;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Value("${regulatedData.schema.path:/regulated_data/schema}")
    private String schemaPath;

    private Date getStartMonth(Integer span) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.add(Calendar.MONTH, 1-span);
        return calendar.getTime();
    }

    @PreAuthorize("@ss.hasPermi('system:regulated_data:query')")
    @PostMapping(value = "/query", produces = "application/json;charset=UTF-8")
    public Object query(@RequestParam("code") String code, @RequestBody JSONObject request) {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        boolean commonRoleFlag = sysUserService.checkUserIsCommonRole(loginUser.getUser());
        Long companyId = sysDeptService.selectCompanyIdByUser(loginUser.getUser());
        code = code.toLowerCase();
        Map<String, Object> options = new HashMap<>();
        String keyName = request.getString("keyName");
        if (keyName != null && !keyName.isEmpty()) {
            options.put("keyName", keyName);
        }
        String valueName = request.getString("valueName");
        if (keyName != null && !valueName.isEmpty()) {
            options.put("valueName", valueName);
        }
        QueryVo queryVo = new QueryVo();
        queryVo.filters.put("company_id", companyId);
        // TODO: [zy] check request with json schema
        if ("project_list".equals(code)) {
            queryVo.filters.put("is_on", true);
            if (!commonRoleFlag){
                String sql = customPermissionService.getProjectAuthorizePermission("p", null, loginUser.getUser());
                queryVo.setCustomPermissionSql(sql);
            }
            return projectService.index(queryVo);
        } else if ("project_summary".equals(code)) {
            if (!commonRoleFlag){
                String sql = customPermissionService.getProjectAuthorizePermission(null, null, loginUser.getUser());
                queryVo.setCustomPermissionSql(sql);
            }
            return projectService.summary(queryVo, options);
        } else if ("alarm_list".equals(code)) {
            if (!commonRoleFlag){
                String sql = customPermissionService.getProjectAuthorizePermission("a", "project_id", loginUser.getUser());
                queryVo.setCustomPermissionSql(sql);
            }
            queryVo.filters.put("project_id", request.getInteger("projectId"));
            return alarmService.index(queryVo);
        } else if ("alarm_summary".equals(code)) {
            if (!commonRoleFlag){
                String sql = customPermissionService.getProjectAuthorizePermission("a", "project_id", loginUser.getUser());
                queryVo.setCustomPermissionSql(sql);
            }
            queryVo.filters.put("project_id", request.getInteger("projectId"));
            return alarmService.summary(queryVo, options);
        } else if ("point_check_summary".equals(code)) {
            queryVo.filters.put("project_id", request.getInteger("projectId"));
            if (!commonRoleFlag){
                String sql = customPermissionService.getProjectAuthorizePermission("a", "project_id", loginUser.getUser());
                queryVo.setCustomPermissionSql(sql);
            }
            return reportDetailService.pointCheckStatusSummary(queryVo, options);
        } else if ("point_check_abnormal_summary_by_month".equals(code)) {
            Date start = getStartMonth(6);
            queryVo.filters.put("start", start);
            queryVo.filters.put("project_id", request.getInteger("projectId"));
            if (!commonRoleFlag){
                String sql = customPermissionService.getProjectAuthorizePermission("a", "project_id", loginUser.getUser());
                queryVo.setCustomPermissionSql(sql);
            }
            return reportDetailService.pointCheckAbnormalSummaryByMonth(queryVo, options);
        } else if ("device_list".equals(code)) {
            queryVo.filters.put("project_id", request.getInteger("projectId"));
            if (!commonRoleFlag){
                String sql = customPermissionService.getProjectAuthorizePermission("tbl_device", "project_id", loginUser.getUser());
                queryVo.setCustomPermissionSql(sql);
            }
            //验证当前用户属于客户公司还是总公司
            boolean flag = sysDeptService.checkIsCustomer(loginUser.getUser().getDeptId());
            if (flag) {
                queryVo.filters.put("customer_name",loginUser.getUsername());
            }
            return deviceService.index(queryVo);
        } else if ("device_summary".equals(code)) {
            queryVo.filters.put("project_id", request.getInteger("projectId"));
            if (!commonRoleFlag){
                String sql = customPermissionService.getProjectAuthorizePermission("tbl_device", "project_id", loginUser.getUser());
                queryVo.setCustomPermissionSql(sql);
            }
            return deviceService.summary(queryVo, options);
        } else if ("province_summary".equals(code)) {
            if (!commonRoleFlag){
                String sql = customPermissionService.getProjectAuthorizePermission("p", null, loginUser.getUser());
                queryVo.setCustomPermissionSql(sql);
            }
            return deviceService.provinceSummary(queryVo);
        } else if ("product_summary".equals(code)) {
            queryVo.filters.put("project_id", request.getInteger("projectId"));
            if (!commonRoleFlag){
                String sql = customPermissionService.getProjectAuthorizePermission("d", "project_id", loginUser.getUser());
                queryVo.setCustomPermissionSql(sql);
            }
            return productService.summary(queryVo, options);
        } else if ("project_device_count".equals(code)) {
            if (!commonRoleFlag){
                String sql = customPermissionService.getProjectAuthorizePermission("p", null, loginUser.getUser());
                queryVo.setCustomPermissionSql(sql);
            }
            return projectService.deviceCount(queryVo, options);
        } else if ("project_terminal_count".equals(code)) {
            if (!commonRoleFlag){
                String sql = customPermissionService.getProjectAuthorizePermission("p", null, loginUser.getUser());
                queryVo.setCustomPermissionSql(sql);
            }
            return projectService.configuredTerminalCount(queryVo, options);
        } else if ("device_and_terminal_count_by_month".equals(code)) {
            Date start = getStartMonth(6);
            queryVo.filters.put("start", start);
            queryVo.filters.put("project_id", request.getInteger("projectId"));
            if (!commonRoleFlag){
                String sql = customPermissionService.getProjectAuthorizePermission("d", "project_id", loginUser.getUser());
                queryVo.setCustomPermissionSql(sql);
            }
            return deviceService.deviceAndTerminalCountByMonth(queryVo);
        } else if ("project_value_by_month".equals(code)) {
            Date start = getStartMonth(6);
            queryVo.filters.put("start", start);
            if (!commonRoleFlag){
                String sql = customPermissionService.getProjectAuthorizePermission("tbl_project", null, loginUser.getUser());
                queryVo.setCustomPermissionSql(sql);
            }
            return projectService.valueByMonth(queryVo, options);
        } else if ("project_status_by_month".equals(code)) {
            Date start = getStartMonth(6);
            queryVo.filters.put("start", start);
            if (!commonRoleFlag){
                String sql = customPermissionService.getProjectAuthorizePermission("tbl_project", null, loginUser.getUser());
                queryVo.setCustomPermissionSql(sql);
            }
            return projectService.statusByMonth(queryVo, options);
        } else if ("user_summary".equals(code)) {
            List<String> roleNames = Arrays.asList("客户设备管理员", "客户巡检工");
            List<Map<String, Object>> result = new ArrayList<>();
            Collection<String> keys = redisCache.keys(Constants.LOGIN_TOKEN_KEY + "*");
            Integer onlineCount = 0;
            for (String key : keys) {
                LoginUser user = redisCache.getCacheObject(key);
                List<SysRole> roles = user.getUser().getRoles();
                for (SysRole role : roles) {
                    if (roleNames.contains(role.getRoleName())) {
                        onlineCount += 1;
                    }
                }
            }
            Map<String, Object> online = new HashMap<>();
            online.put("label", "在线");
            online.put("value", onlineCount);
            result.add(online);
            queryVo.filters.put("role_names", roleNames);
            List<Map<String, Object>> totalValues = sysUserMapper.summary(queryVo);
            for (Map<String, Object> item : totalValues) {
                Map<String, Object> itemMap = new HashMap<>();
                itemMap.put("label", item.get("role_name"));
                itemMap.put("value", item.get("count"));
                result.add(itemMap);
            }
            // SysUser user = new SysUser();
            // user.setStatus("0");
            // user.setDelFlag("0");
            // List<SysUser> users = sysUserService.selectUserList(user);
            // Map<String, Object> total = new HashMap<>();
            // total.put("label", "总数");
            // total.put("value", users.size());
            // result.add(total);
            return result;
        } else if ("user_summary_by_month".equals(code)) {
            Date start = getStartMonth(6);
            queryVo.filters.put("start", start);
            queryVo.filters.put("role_names", Arrays.asList("客户设备管理员", "客户巡检工"));
            return sysUserService.summaryByMonth(queryVo);
        }
        return null;
    }

    @PreAuthorize("@ss.hasPermi('system:regulated_data:schema')")
    @GetMapping(value = "/schema", produces = "application/json;charset=UTF-8")
    public AjaxResult schema(@RequestParam("code") String code) {
        JSONObject schema = null;
        code = code.toLowerCase();
        String filePath = String.format("%s/%s.json", schemaPath, code);
        try {
            String content = FileService.load(filePath, false);
            schema = JSONObject.parseObject(content);
        } catch (Exception e) {
            log.info("",e);
            StackTraceElement[] traces = e.getStackTrace();
            for (StackTraceElement trace : traces) {
                log.debug(trace.toString());
            }
        }
        return AjaxResult.success(schema);
    }
}
